#include <stdio.h>
#include <avr/io.h>
#include <avr/iom644.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <string.h>
#include "usart_utils.h"

#define LIGHTS PORTB

void process_turn_on(unsigned char aux);
void process_turn_off(unsigned char aux);
void process_toggle(unsigned char aux);

int
main(void)
{
	char buffer[50] = { };
	int mode = 0;
	char value;

	USART_Init(25);
	DDRB = 0xFF;

	sei();

	while(1) {

		int i = 0;
		char aux = 0;

		/* Se lee cada caracter hasta encontrar un enter. */

		do {
			aux = USART_Receive();
			buffer[i] = aux;
			USART_Transmit(aux);
			i++;

		} while (aux != '\r');

		buffer[i-1] = 0;
		USART_Transmit('\n');

		if (strcmp(buffer, "turn_on") == 0) {

			USART_Send_String("Modo actual TURN_ON\n\r");
			mode = 0;

		} else if (strcmp(buffer, "turn_off") == 0) {

			USART_Send_String("Modo actual TURN_OFF\n\r");
			mode = 1;

		} else if (strcmp(buffer, "toggle") == 0) {

			USART_Send_String("Modo actual TOGGLE\n\r");
			mode = 2;

		} else if (buffer[0] >= '1' && buffer[0] <= '8') {
			value = buffer[0];
			switch (mode) {
				case 0:
					process_turn_on(value);
					break;
				case 1:
					process_turn_off(value);
					break;
				case 2:
					process_toggle(value);
					break;
				default:
					break;
			}

			USART_Send_String("Comando procesado!\n\r");

		} else {

			USART_Send_String("Error en el comando!\n\r");

		}
	}
}

void
process_turn_on(unsigned char aux) {

	int lights = LIGHTS;

	int value = aux - '0' - 1;
	lights &= ~(0x01<<value);

	LIGHTS = lights;
	return;
}

void
process_turn_off(unsigned char aux) {

	int lights = LIGHTS;

	int value = aux - '0' - 1;
	lights |= (0x01<<value);

	LIGHTS = lights;
	return;
}

void
process_toggle(unsigned char aux) {

	int lights = LIGHTS;

	int value = aux - '0' - 1;

	if ((lights & (1<<value)) == 0) {
		lights |= (0x01<<value);
	} else {
		lights &= ~(0x01<<value);
	}

	LIGHTS = lights;

	return;
}
